package org.beetl.core.engine;

import org.beetl.core.Context;
import org.beetl.core.GroupTemplate;
import org.beetl.core.exception.BeetlException;
import org.beetl.core.fun.MethodInvoker;
import org.beetl.core.fun.ObjectUtil;
import org.beetl.core.misc.ALU;
import org.beetl.core.om.AABuilder;
import org.beetl.core.om.DefaultAAFactory;
import org.beetl.core.om.ReflectBeanAA;
import org.beetl.core.statement.*;

import java.math.BigDecimal;

import static org.beetl.core.misc.ALU.STRING;

/**
 * 允许字符串参与比较
 */
public class CompareExtEngine extends FastRuntimeEngine
{

    public CompareExtEngine() {
        super();

    }

	@Override
	protected GrammarCreator getGrammarCreator(GroupTemplate groupTemplate) {
		GrammarCreator result = new CompareExtGrammarCreator();
		super.setStrictDisableGrammars(result, groupTemplate);
		return result;
	}

	/**
	 * 重新创建语法树
	 */
	public class CompareExtGrammarCreator extends GrammarCreator {

		@Override
		public CompareExpression createCompare(Expression a, Expression b, short mode, GrammarToken token) {
			disableSyntaxCheck(Compare);
			return new CompareExtExpression(a, b, mode, token);
		}
	}

	/**
	 * 表达式覆盖
	 */
	public class CompareExtExpression extends CompareExpression {

		public CompareExtExpression(Expression a, Expression b, short mode, GrammarToken token) {
			super(a, b, mode, token);
		}

		public Object evaluate(Context ctx) {
			Object x = a.evaluate(ctx);
			Object y = b.evaluate(ctx);
			int type = ALU.getAluType(x, y);
			if (type == STRING) {
				if (!(ALU.getAluType(x) == STRING && ALU.getAluType(y) == STRING)) {
					//某一个是字符串，另外一个number类型。粗糙的实现
					BigDecimal left = new BigDecimal(x.toString());
					BigDecimal right = new BigDecimal(y.toString());
					int ret = left.compareTo(right);
					switch (compareMode) {
						case EQUAL:
							return ret == 0;
						case NOT_EQUAL:
							return ret != 0;
						case LARGE_EQUAL:
							return ret <= 0;
						case LARGE:
							return ret > 0;
						case LESS:
							return ret < 0;
						case LESS_EQUAL:
							return ret <= 0;
						default:
							throw new RuntimeException("不可能发生");
					}
				}
			}

			return super.evaluate(ctx);

		}
	}


}
